<template>
  <div class="modern-table-container">
    <!-- 表格头部操作区 -->
    <div v-if="$slots.header || title" class="table-header">
      <div v-if="title" class="table-title-section">
        <h3 class="table-title">{{ title }}</h3>
        <p v-if="description" class="table-description">{{ description }}</p>
      </div>
      <div v-if="$slots.header" class="table-header-actions">
        <slot name="header" />
      </div>
    </div>

    <!-- 搜索和筛选区域 -->
    <div v-if="searchable || $slots.filters" class="table-filters">
      <div v-if="searchable" class="table-search">
        <div class="relative">
          <MagnifyingGlassIcon class="search-icon" />
          <input
            v-model="searchQuery"
            type="text"
            :placeholder="searchPlaceholder"
            class="search-input"
          />
        </div>
      </div>
      <div v-if="$slots.filters" class="table-filter-actions">
        <slot name="filters" />
      </div>
    </div>

    <!-- 表格主体 -->
    <div class="table-wrapper" :class="{ 'table-wrapper-loading': loading }">
      <!-- 移动端卡片视图 -->
      <div v-if="isMobile && mobileCardView" class="mobile-card-view">
        <div v-if="!filteredData.length && !loading" class="empty-state">
          <slot name="empty">
            <div class="empty-content">
              <DocumentIcon class="empty-icon" />
              <p class="empty-text">{{ emptyText }}</p>
            </div>
          </slot>
        </div>
        
        <div v-else class="mobile-cards-grid">
          <div
            v-for="(item, index) in paginatedData"
            :key="getRowKey(item, index)"
            class="mobile-card"
            @click="handleRowClick(item, index)"
          >
            <slot name="mobileCard" :item="item" :index="index">
              <div class="mobile-card-content">
                <div v-for="column in visibleColumns" :key="column.key" class="mobile-card-field">
                  <span class="mobile-field-label">{{ column.label }}:</span>
                  <span class="mobile-field-value">
                    <slot
                      :name="`cell-${column.key}`"
                      :item="item"
                      :column="column"
                      :index="index"
                      :value="getColumnValue(item, column.key)"
                    >
                      {{ getColumnValue(item, column.key) }}
                    </slot>
                  </span>
                </div>
              </div>
            </slot>
          </div>
        </div>
      </div>

      <!-- 桌面端表格视图 -->
      <div v-else class="table-scroll-wrapper">
        <table class="modern-table">
          <!-- 表头 -->
          <thead class="table-head">
            <tr>
              <th
                v-for="column in visibleColumns"
                :key="column.key"
                :class="getHeaderClasses(column)"
                @click="handleSort(column)"
              >
                <div class="header-content">
                  <span>{{ column.label }}</span>
                  <div v-if="column.sortable" class="sort-indicators">
                    <ChevronUpIcon
                      :class="getSortIconClasses(column.key, 'asc')"
                    />
                    <ChevronDownIcon
                      :class="getSortIconClasses(column.key, 'desc')"
                    />
                  </div>
                </div>
              </th>
            </tr>
          </thead>

          <!-- 表体 -->
          <tbody class="table-body">
            <tr v-if="!filteredData.length && !loading" class="empty-row">
              <td :colspan="visibleColumns.length" class="empty-cell">
                <slot name="empty">
                  <div class="empty-content">
                    <DocumentIcon class="empty-icon" />
                    <p class="empty-text">{{ emptyText }}</p>
                  </div>
                </slot>
              </td>
            </tr>
            
            <tr
              v-for="(item, index) in paginatedData"
              :key="getRowKey(item, index)"
              :class="getRowClasses(item, index)"
              @click="handleRowClick(item, index)"
            >
              <td
                v-for="column in visibleColumns"
                :key="column.key"
                :class="getCellClasses(column)"
              >
                <slot
                  :name="`cell-${column.key}`"
                  :item="item"
                  :column="column"
                  :index="index"
                  :value="getColumnValue(item, column.key)"
                >
                  {{ getColumnValue(item, column.key) }}
                </slot>
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- 加载状态 -->
      <div v-if="loading" class="table-loading">
        <LoadingSpinner size="lg" color="primary" />
        <p class="loading-text">{{ loadingText }}</p>
      </div>
    </div>

    <!-- 分页器 -->
    <div v-if="pagination && totalPages > 1" class="table-pagination">
      <div class="pagination-info">
        <span class="pagination-text">
          共 {{ totalItems }} 条记录，第 {{ currentPage }} / {{ totalPages }} 页
        </span>
      </div>
      <div class="pagination-controls">
        <ModernButton
          variant="outline"
          size="sm"
          :disabled="currentPage <= 1"
          @click="goToPage(currentPage - 1)"
        >
          <ChevronLeftIcon class="w-4 h-4" />
        </ModernButton>
        
        <div class="pagination-numbers">
          <button
            v-for="page in visiblePages"
            :key="page"
            :class="getPaginationButtonClasses(page)"
            @click="goToPage(page)"
          >
            {{ page }}
          </button>
        </div>
        
        <ModernButton
          variant="outline"
          size="sm"
          :disabled="currentPage >= totalPages"
          @click="goToPage(currentPage + 1)"
        >
          <ChevronRightIcon class="w-4 h-4" />
        </ModernButton>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import {
  MagnifyingGlassIcon,
  DocumentIcon,
  ChevronUpIcon,
  ChevronDownIcon,
  ChevronLeftIcon,
  ChevronRightIcon,
} from '@heroicons/vue/24/outline'
import LoadingSpinner from './LoadingSpinner.vue'
import ModernButton from './ModernButton.vue'
import { useBreakpoints } from '@/composables/useTheme'

export interface TableColumn {
  key: string
  label: string
  sortable?: boolean
  width?: string
  align?: 'left' | 'center' | 'right'
  fixed?: 'left' | 'right'
}

export interface ModernTableProps {
  // 数据
  data?: any[]
  columns?: TableColumn[]
  loading?: boolean
  
  // 标题和描述
  title?: string
  description?: string
  
  // 搜索
  searchable?: boolean
  searchPlaceholder?: string
  searchFields?: string[]
  
  // 排序
  defaultSortKey?: string
  defaultSortOrder?: 'asc' | 'desc'
  
  // 分页
  pagination?: boolean
  pageSize?: number
  
  // 样式
  hoverable?: boolean
  striped?: boolean
  bordered?: boolean
  mobileCardView?: boolean
  
  // 文本
  emptyText?: string
  loadingText?: string
  
  // 行配置
  rowKey?: string | ((row: any, index: number) => string)
  clickableRows?: boolean
}

const props = withDefaults(defineProps<ModernTableProps>(), {
  data: () => [],
  columns: () => [],
  loading: false,
  searchable: false,
  searchPlaceholder: '搜索...',
  searchFields: () => [],
  pagination: true,
  pageSize: 10,
  hoverable: true,
  striped: false,
  bordered: false,
  mobileCardView: true,
  emptyText: '暂无数据',
  loadingText: '加载中...',
  rowKey: 'id',
  clickableRows: false,
})

const emit = defineEmits<{
  rowClick: [row: any, index: number]
  sort: [column: string, order: 'asc' | 'desc']
  search: [query: string]
}>()

const { isMobile } = useBreakpoints()

// 搜索状态
const searchQuery = ref('')

// 排序状态
const sortKey = ref(props.defaultSortKey || '')
const sortOrder = ref<'asc' | 'desc'>(props.defaultSortOrder || 'asc')

// 分页状态
const currentPage = ref(1)

// 可见列
const visibleColumns = computed(() => props.columns)

// 过滤后的数据
const filteredData = computed(() => {
  if (!searchQuery.value) return props.data

  const query = searchQuery.value.toLowerCase()
  const searchFields = props.searchFields.length 
    ? props.searchFields 
    : props.columns.map(col => col.key)

  return props.data.filter(item => {
    return searchFields.some(field => {
      const value = getColumnValue(item, field)
      return String(value).toLowerCase().includes(query)
    })
  })
})

// 排序后的数据
const sortedData = computed(() => {
  if (!sortKey.value) return filteredData.value

  return [...filteredData.value].sort((a, b) => {
    const aValue = getColumnValue(a, sortKey.value)
    const bValue = getColumnValue(b, sortKey.value)

    let result = 0
    if (aValue < bValue) result = -1
    else if (aValue > bValue) result = 1

    return sortOrder.value === 'desc' ? -result : result
  })
})

// 分页计算
const totalItems = computed(() => sortedData.value.length)
const totalPages = computed(() => 
  props.pagination ? Math.ceil(totalItems.value / props.pageSize) : 1
)

const paginatedData = computed(() => {
  if (!props.pagination) return sortedData.value

  const start = (currentPage.value - 1) * props.pageSize
  const end = start + props.pageSize
  return sortedData.value.slice(start, end)
})

// 可见页码
const visiblePages = computed(() => {
  const total = totalPages.value
  const current = currentPage.value
  const delta = 2

  const pages = []
  const start = Math.max(1, current - delta)
  const end = Math.min(total, current + delta)

  for (let i = start; i <= end; i++) {
    pages.push(i)
  }

  return pages
})

// 获取列值
const getColumnValue = (item: any, key: string) => {
  return key.split('.').reduce((obj, k) => obj?.[k], item) ?? ''
}

// 获取行key
const getRowKey = (row: any, index: number) => {
  if (typeof props.rowKey === 'function') {
    return props.rowKey(row, index)
  }
  return row[props.rowKey] ?? index
}

// 样式类计算
const getHeaderClasses = (column: TableColumn) => [
  'table-header-cell',
  {
    'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800': column.sortable,
    [`text-${column.align}`]: column.align && column.align !== 'left',
  }
]

const getRowClasses = (item: any, index: number) => [
  'table-row',
  {
    'table-row-hoverable': props.hoverable,
    'table-row-striped': props.striped && index % 2 === 1,
    'table-row-clickable': props.clickableRows,
  }
]

const getCellClasses = (column: TableColumn) => [
  'table-cell',
  {
    [`text-${column.align}`]: column.align && column.align !== 'left',
  }
]

const getSortIconClasses = (columnKey: string, direction: 'asc' | 'desc') => [
  'sort-icon',
  {
    'sort-icon-active': sortKey.value === columnKey && sortOrder.value === direction,
  }
]

const getPaginationButtonClasses = (page: number) => [
  'pagination-number',
  {
    'pagination-number-active': page === currentPage.value,
  }
]

// 事件处理
const handleSort = (column: TableColumn) => {
  if (!column.sortable) return

  if (sortKey.value === column.key) {
    sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'
  } else {
    sortKey.value = column.key
    sortOrder.value = 'asc'
  }

  emit('sort', column.key, sortOrder.value)
}

const handleRowClick = (row: any, index: number) => {
  if (props.clickableRows) {
    emit('rowClick', row, index)
  }
}

const goToPage = (page: number) => {
  if (page >= 1 && page <= totalPages.value) {
    currentPage.value = page
  }
}

// 监听搜索
watch(searchQuery, (newQuery) => {
  currentPage.value = 1
  emit('search', newQuery)
})

// 监听数据变化重置分页
watch(() => props.data, () => {
  currentPage.value = 1
})
</script>

<style scoped>
.modern-table-container {
  @apply space-y-4;
}

/* 表格头部 */
.table-header {
  @apply flex items-start justify-between;
}

.table-title-section {
  @apply space-y-1;
}

.table-title {
  @apply text-lg font-semibold text-gray-900 dark:text-gray-100 font-heading;
}

.table-description {
  @apply text-sm text-gray-600 dark:text-gray-400;
}

.table-header-actions {
  @apply flex items-center space-x-2;
}

/* 搜索和筛选 */
.table-filters {
  @apply flex items-center justify-between space-x-4;
}

.table-search {
  @apply flex-1 max-w-sm;
}

.search-icon {
  @apply absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400;
}

.search-input {
  @apply w-full pl-10 pr-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md 
         bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 
         placeholder-gray-500 dark:placeholder-gray-400
         focus:ring-2 focus:ring-primary-500 focus:border-transparent
         transition-all duration-200;
}

.table-filter-actions {
  @apply flex items-center space-x-2;
}

/* 表格包装器 */
.table-wrapper {
  @apply relative bg-white dark:bg-gray-800 rounded-md border border-gray-200 dark:border-gray-700 overflow-hidden;
}

.table-wrapper-loading {
  @apply min-h-[200px];
}

.table-scroll-wrapper {
  @apply overflow-x-auto;
}

/* 表格样式 */
.modern-table {
  @apply w-full;
}

.table-head {
  @apply bg-gray-50 dark:bg-gray-700;
}

.table-header-cell {
  @apply px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider transition-colors duration-200;
}

.header-content {
  @apply flex items-center justify-between;
}

.sort-indicators {
  @apply flex flex-col ml-2;
}

.sort-icon {
  @apply w-3 h-3 text-gray-300 dark:text-gray-600 transition-colors duration-200;
}

.sort-icon-active {
  @apply text-primary-500;
}

.table-body {
  @apply bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700;
}

.table-row {
  @apply transition-colors duration-150;
}

.table-row-hoverable {
  @apply hover:bg-gray-50 dark:hover:bg-gray-700;
}

.table-row-striped {
  @apply bg-gray-50 dark:bg-gray-750;
}

.table-row-clickable {
  @apply cursor-pointer;
}

.table-cell {
  @apply px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100;
}

/* 移动端卡片视图 */
.mobile-card-view {
  @apply lg:hidden;
}

.mobile-cards-grid {
  @apply space-y-3;
}

.mobile-card {
  @apply bg-white dark:bg-gray-800 rounded-md border border-gray-200 dark:border-gray-700 p-4 
         hover:shadow-md dark:hover:shadow-soft-dark transition-all duration-200;
}

.mobile-card-content {
  @apply space-y-2;
}

.mobile-card-field {
  @apply flex justify-between items-center;
}

.mobile-field-label {
  @apply text-sm font-medium text-gray-500 dark:text-gray-400;
}

.mobile-field-value {
  @apply text-sm text-gray-900 dark:text-gray-100 text-right;
}

/* 空状态 */
.empty-row {
  @apply hover:bg-transparent;
}

.empty-cell {
  @apply px-6 py-12 text-center;
}

.empty-content {
  @apply flex flex-col items-center space-y-2;
}

.empty-icon {
  @apply w-12 h-12 text-gray-400 dark:text-gray-600;
}

.empty-text {
  @apply text-sm text-gray-500 dark:text-gray-400;
}

/* 加载状态 */
.table-loading {
  @apply absolute inset-0 bg-white/80 dark:bg-gray-800/80 flex flex-col items-center justify-center space-y-2 backdrop-blur-sm;
}

.loading-text {
  @apply text-sm text-gray-600 dark:text-gray-400;
}

/* 分页器 */
.table-pagination {
  @apply flex items-center justify-between px-4 py-3 bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 rounded-b-md;
}

.pagination-info {
  @apply flex-1;
}

.pagination-text {
  @apply text-sm text-gray-700 dark:text-gray-300;
}

.pagination-controls {
  @apply flex items-center space-x-2;
}

.pagination-numbers {
  @apply flex items-center space-x-1;
}

.pagination-number {
  @apply px-3 py-1 text-sm rounded-md border border-gray-300 dark:border-gray-600 
         bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300
         hover:bg-gray-50 dark:hover:bg-gray-700 
         transition-colors duration-200;
}

.pagination-number-active {
  @apply bg-primary-500 text-white border-primary-500 hover:bg-primary-600;
}

/* 响应式调整 */
@media (max-width: 640px) {
  .table-filters {
    @apply flex-col items-stretch space-x-0 space-y-3;
  }
  
  .table-pagination {
    @apply flex-col items-stretch space-y-3;
  }
  
  .pagination-controls {
    @apply justify-center;
  }
}
</style>
